﻿using System.Windows.Forms;
using System;
using System.Collections;

namespace MutsiEngine
{
    class Game : GameCore
    {
        Camera camera = new Camera();
        GameObject teapot = new GameObject();
        GameObject plane = new GameObject();
        Billboard billboard = new Billboard();
        Texture grassTexture = new Texture();
        Texture grassBillboardTexture = new Texture();
        Texture fancypatternTexture = new Texture();

        GameObject gameObject = new GameObject();

        Billboard[] grassArray = new Billboard[2000];

        private uint vertexShader, fragmentShader, billboardShader;
        private uint ShaderProgram;

        protected override void Initialize()
        {
            base.Initialize();
            //Initialize here
            cameraManager.Add("PlayerCam", camera);
            LoadContent();
        }

        protected override void LoadContent()
        {
            teapot.LoadContent("Models/teapot.obj");
            teapot.mesh.CreateDisplayList(Gl);

            billboard = new Billboard();
            billboard.mesh.CreateDisplayList(Gl);
            Random random = new Random();
            for (int i = 0; i < 2000; i++)
            {
                grassArray[i] = new Billboard();
                grassArray[i].mesh = billboard.mesh;
                float x = (float)random.NextDouble() * 8f - 4f;
                float y = (float)random.NextDouble() * 0.25f;
                float z = (float)(2000-i)/250f-4f + (float)(random.NextDouble());
                grassArray[i].Move(new Vector3(x, -y, z));
                grassArray[i].target.Y = (float)random.NextDouble() * 160f - 80f;
                float scale =  (float)random.NextDouble();
                grassArray[i].Scale = new Vector3(scale, scale, scale);
            }
            SortedList grassList = new SortedList();

            camera.Position.Y = 1;

            plane.mesh = Primitives.Plane(Vector3.Up, 4f);
            plane.mesh.CreateDisplayList(Gl);

            gameObject.LoadContent("Models/teapot.obj");
            gameObject.mesh.CreateDisplayList(Gl);

            vertexShader = ContentLoader.LoadShader("Shaders/Billboard.vert", Gl, SharpGL.OpenGL.GL_VERTEX_SHADER);
            billboardShader = ContentLoader.LoadShader("Shaders/Billboard.frag", Gl, SharpGL.OpenGL.GL_FRAGMENT_SHADER);
            fragmentShader = ContentLoader.LoadShader("Shaders/Diffuse.frag", Gl, SharpGL.OpenGL.GL_FRAGMENT_SHADER);

            ShaderProgram = Gl.CreateProgram();
            Gl.AttachShader(ShaderProgram, vertexShader);
            Gl.AttachShader(ShaderProgram, billboardShader);
            Gl.LinkProgram(ShaderProgram);
            Gl.UseProgram(ShaderProgram);

            grassTexture = ContentLoader.LoadTexture("Content/Textures/grass.png", Gl);
            grassBillboardTexture = ContentLoader.LoadTexture("Content/Textures/GrassBillboard.png", Gl);
            fancypatternTexture = ContentLoader.LoadTexture("Content/Textures/fancypattern.bmp", Gl);

            base.LoadContent();
        }

        protected override void Update(GameTime gameTime)
        {
            if (input.IsKeyDown(Keys.W))
            {
                cameraManager.ActiveCamera.Move(new Vector3(0.0f, 0, 0.1f));
            }
            if (input.IsKeyDown(Keys.S))
            {
                cameraManager.ActiveCamera.Move(new Vector3(0.0f, 0, -0.1f));
            }
            if (input.IsKeyDown(Keys.A))
            {
                cameraManager.ActiveCamera.Move(new Vector3(-0.1f, 0, 0));
            }
            if (input.IsKeyDown(Keys.D))
            {
                cameraManager.ActiveCamera.Move(new Vector3(0.1f, 0, 0));
            }
            if (input.IsKeyDown(Keys.D1))
            {
                Gl.Enable(SharpGL.OpenGL.GL_POLYGON_SMOOTH);
                //Gl.PolygonMode(SharpGL.OpenGL.GL_FRONT_AND_BACK, SharpGL.OpenGL.GL_FILL);
            }
            if (input.IsKeyDown(Keys.D2))
            {
                Gl.Disable(SharpGL.OpenGL.GL_POLYGON_SMOOTH);
                //Gl.PolygonMode(SharpGL.OpenGL.GL_FRONT_AND_BACK, SharpGL.OpenGL.GL_LINE);
            }
            if (input.IsKeyDown(Keys.F1))
            {
                SetRenderWindowResolution(640, 480);
                cameraManager.ActiveCamera.AspectRatio = (float)640 / 480;
            }
            if (input.IsKeyDown(Keys.F2))
            {
                SetRenderWindowResolution(1024, 768);
                cameraManager.ActiveCamera.AspectRatio = (float)1024 / 768;
            }
            if (input.IsKeyDown(Keys.F3))
            {
                SetRenderWindowResolution(1280, 720);
                cameraManager.ActiveCamera.AspectRatio = (float)1280 / 720;
            }

            billboard.Update(camera.Target);

            // Set Camera Perspective
            cameraManager.ActiveCamera.SetGLPerspective(Gl);

            // Set Camera LookAt
            cameraManager.ActiveCamera.SetGLLookAt(Gl);

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            ClearScreen(VectorColor.Black);
            grassTexture.Bind(Gl);
            plane.Draw(gameTime,Gl);

            Gl.Enable(SharpGL.OpenGL.GL_BLEND);
            
            grassBillboardTexture.Bind(Gl);
            billboard.Draw(gameTime, Gl, ShaderProgram);
            Gl.Disable(SharpGL.OpenGL.GL_DEPTH_TEST);
            foreach (Billboard bilb in grassArray)
            {
                //int alphaName = Gl.GetUniformLocation(ShaderProgram, "alpha");
                //Gl.Uniform1(alphaName, MutsiMath.Clamp<float>(8f - Vector3.Distance(camera.Position, bilb.Position), 0f, 1f));
                bilb.Draw(gameTime, Gl, ShaderProgram);
            }
           // Console.ReadKey();
            Gl.Disable(SharpGL.OpenGL.GL_BLEND);
            Gl.Enable(SharpGL.OpenGL.GL_DEPTH_TEST);

            base.Draw(gameTime);
        }
    }
}
